#!/usr/bin/perl -w

#      Copyright (C) 2012 Wind River Systems, Inc.
#
#      Copyright (C) 2010 Intel Corporation
#
#   
#   This program is free software: you can redistribute it and/or modify
#   it under the terms of the GNU General Public License as published by
#   the Free Software Foundation, either version 3 of the License.
#   
#   This program is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#   GNU General Public License for more details.
#   
#   You should have received a copy of the GNU General Public License
#   along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
#   As a special exception, you may create a larger work that contains
#   part or all of the autospectacle output and distribute that work
#   under terms of your choice.
#   Alternatively, if you modify or redistribute autospectacle itself, 
#   you may (at your option) remove this special exception.
#   
#   This special exception was modeled after the bison exception 
#   (as done by the Free Software Foundation in version 2.2 of Bison)
#


use File::Temp qw(tempdir);
use File::Path qw(mkpath rmtree); 
use File::Spec (); 
use File::Basename qw(basename dirname);


my $name = "";
my $predef_version = "TO BE FILLED IN";
my $version = $predef_version;
my $pversion = $predef_version;
my $description = "";
my $summary = "";
my $url = "";
my $homepage = "";
my @depends;
my @rdepends;
my @rawpythondeps;
my $configure = "";
my $localename = "";
my @sources;
my @mainfiles;
my @patches;

my $md5sum = "";
my $sh256sum = "";
my @inherits;

my $printed_subpackages = 0;
my $fulldir = "";

my $builder = "";


my $oscmode = 0;
my $python = 0;

my @banned_pkgconfig;
my %failed_commands;
my %failed_libs;
my %failed_headers;



######################################################################
#
# License management
#
# We store the sha1sum of common COPYING files in an associative array
# %licenses. 
#
# For all matching sha1's in the tarball, we then push the result
# in the @license array (which we'll dedupe at the time of printing).
# 

my %licenses;
my @license;
my %lic_files;

sub setup_licenses
{
	$licenses{"06877624ea5c77efe3b7e39b0f909eda6e25a4ec"} = "GPLv2";
	$licenses{"075d599585584bb0e4b526f5c40cb6b17e0da35a"} = "GPLv2";
	$licenses{"10782dd732f42f49918c839e8a5e2894c508b079"} = "GPLv2";
	$licenses{"2d29c273fda30310211bbf6a24127d589be09b6c"} = "GPLv2";
	$licenses{"4df5d4b947cf4e63e675729dd3f168ba844483c7"} = "LGPLv2.1";
	$licenses{"503df7650052cf38efde55e85f0fe363e59b9739"} = "GPLv2";
	$licenses{"5405311284eab5ab51113f87c9bfac435c695bb9"} = "GPLv2";
	$licenses{"5fb362ef1680e635fe5fb212b55eef4db9ead48f"} = "LGPLv2";
	$licenses{"68c94ffc34f8ad2d7bfae3f5a6b996409211c1b1"} = "GPLv2";
	$licenses{"66c77efd1cf9c70d4f982ea59487b2eeb6338e26"} = "LGPLv2.1";
	$licenses{"74a8a6531a42e124df07ab5599aad63870fa0bd4"} = "GPLv2";
	$licenses{"8088b44375ef05202c0fca4e9e82d47591563609"} = "LGPLv2.1";
	$licenses{"8624bcdae55baeef00cd11d5dfcfa60f68710a02"} = "GPLv3";
	$licenses{"8e57ffebd0ed4417edc22e3f404ea3664d7fed27"} = "MIT";
	$licenses{"99b5245b4714b9b89e7584bfc88da64e2d315b81"} = "BSD";
	$licenses{"aba8d76d0af67d57da3c3c321caa59f3d242386b"} = "MPLv1.1";
	$licenses{"bf50bac24e7ec325dbb09c6b6c4dcc88a7d79e8f"} = "LGPLv2";
	$licenses{"caeb68c46fa36651acf592771d09de7937926bb3"} = "LGPLv2.1";
	$licenses{"dfac199a7539a404407098a2541b9482279f690d"} = "GPLv2";
	$licenses{"e60c2e780886f95df9c9ee36992b8edabec00bcc"} = "LGPLv2.1";
	$licenses{"c931aad3017d975b7f20666cde0953234a9efde3"} = "GPLv2";
}

sub guess_license_from_file {
	my ($copying) = @_;

	if (!-e $copying)  {
		return;
	}

	my $sha1output = `sha1sum $copying`;
	$sha1output =~ /^([a-zA-Z0-9]*) /;
	my $sha1 = $1;

	chomp($sha1);

	#
	# if sha1 matches.. push there result
	#
	if (defined($licenses{$sha1})) {
		my $lic = $licenses{$sha1};
		push(@license, $lic);

		my $md5output = `md5sum $copying`;
		$md5output =~ /^([a-zA-Z0-9]*) /;
		my $md5 = $1;
		chomp($md5);
		$lic_files{$copying} = $md5
	}

	#
	# if file is found, and licence of python
	# package is already aquired, add file.
        #
	if ($python == 1 && @license != 0) {
	        my $md5output = `md5sum $copying`;
	        $md5output =~ /^([a-zA-Z0-9]*) /;
	        my $md5 = $1;
	        chomp($md5);
	        $lic_files{$copying} = $md5
	}

	#
	# We also must make sure that the COPYING/etc files
	# end up in the main package as %doc..
	#
	$copying =~ s/$fulldir//g;
	$copying =~ s/^\///g;
	$copying = "\"\%doc " . $copying ."\"";

	push(@mainfiles, $copying);
}

sub print_license
{
	my $count = @license;
	if ($count == 0) {
		print OUTFILE "License: TO BE FILLED IN\n";
		return;
	}

	# remove dupes
	undef %saw;
	@saw{@license} = ();
    	@out = sort keys %saw;

	print OUTFILE "License    : ";
	foreach (@out) {
		print OUTFILE "$_ ";
	}
	print OUTFILE "\n";
}

# end of license section
#
#######################################################################

######################################################################
#
# Package group management
#
# We set up an associative array of regexp patterns, where the content
# of the array is the name of the group.
#
# These are "strings of regexps", which means one needs to escape
# everything, and if you want the actual regexp to have a \,
# it needs to be a \\ in this string.

my %group_patterns;
my @groups;
my $group   = "TO_BE/FILLED_IN";

sub setup_group_rules
{
	$group_patterns{"^\\/usr\\/lib\\/.*so"} = "System/Libraries";
	$group_patterns{"^\\/lib\\/.*so"} = "System/Libraries";
	$group_patterns{"^\\/bin\\/.*"} = "Applications/System";
	$group_patterns{"^\\/sbin\\/.*"} = "Applications/System";
	$group_patterns{"^\\/usr\\/sbin\\/.*"} = "Applications/System";
}

sub guess_group_from_file
{
	my ($filename) = @_;	
	while (($key,$value) = each %group_patterns) {
		if ($filename =~ /$key/) {
			push(@groups, $value);
		}
	}
				
}

# end of group section
#
######################################################################


######################################################################
#
# Files and package section
#
# This section creates the %files section, but also decides which
# subpackages (devel and/or doc) we need to have.
#
# We start out with the @allfiles array, which will contain all the
# files installed by the %build phase of the package. The task is
# to sort these into @mainfiles, @develfiles and @docfiles.
# In addition, an attempt is made to compress the files list by
# replacing full filenames with "*" patterns.
#
# For this we use a set of regexps from the @files_match array,
# which are then used as index to three associative arrays:
# %files_target : numerical index for which package the regexp
#                 would place the file at hand.
#                  0 - main package
#                  1 - devel package
#                  2 - doc package
#                 99 - don't package this at all
#
# %files_from: regexp to match the file against for filename-wildcarding
# %files_to  : pattern to append to the ()'d part of %files_from to end up
#              with the filename-wildcard.
 
my @allfiles;
my @develfiles;
my @docfiles;


my @files_match;
my %files_target;
my %files_from;
my %files_to;

my $totaldocs = 0;


sub add_files_rule
{
	my ($match, $target, $from, $to) =@_;
	push(@files_match, $match);
	$files_target{"$match"} = $target;
	
	if (length($from) > 0) {
		$files_from{"$match"} = $from;
	}

	if (length($to) > 0) {
		$files_to{"$match"} = $to;
	}
}

sub setup_files_rules
{

#
# Files for the Main package
# 

	add_files_rule("^\\/usr\\/lib\\/[a-z0-9A-Z\\_\\-\\.]+\\.so\\.", 0, 
			"(\\/usr\\/lib\\/.*\\.so\\.).*", "\*");


	add_files_rule("^\\/usr\\/share\\/omf\\/", 0, 
			"(\\/usr\\/share\\/omf\\/.*?\\/).*", "\*");
			
#
# Files for the Devel subpackage
#
	add_files_rule("^\\/usr\\/share\\/gir-1\\.0\\/[a-z0-9A-Z\\_\\-\\.]+\\.gir\$", 1, 
			"(\\/usr\\/share\\/gir-1\\.0\/).*", "\*\.gir");
	add_files_rule("^\\/usr\\/lib\\/girepository-1\\.0\\/[a-z0-9A-Z\\_\\-\\.]+\\.typelib\$", 1, 
			"(\\/usr\\/lib\\/girepository-1\\.0\/).*", "\*\.typelib");
	add_files_rule("^\\/usr\\/include\\/[a-z0-9A-Z\\_\\-\\.]+\\.h\$", 1, 
			"(\\/usr\\/include\/).*", "\*\.h");
	add_files_rule("^\\/usr\\/include\\/[a-z0-9A-Z\\_\\-\\.]+\\/.*?\\.h\$", 1, 
			"(\\/usr\\/include\\/[a-z0-9A-Z\\_\\-\\.]+\\/.*?)[a-z0-9A-Z\\_\\-\\.]+\\.h", "\*\.h");
	add_files_rule("^\\/usr\\/lib\\/[a-z0-9A-Z\\_\\-\\.]+\\.so\$", 1, 
			"(\\/usr\\/lib\\/).*\\.so\$", "\*.so");
	add_files_rule("^\\/usr\\/lib\\/pkgconfig\\/[a-z0-9A-Z\\_\\-\\.\+]+\\.pc\$", 1, 
			"(\\/usr\\/lib\\/pkgconfig\\/).*\\.pc\$", "\*.pc");
	add_files_rule("^\\/usr\\/share\\/aclocal", 1, "", "");
	add_files_rule("^\\/usr\\/lib\\/qt4\\/mkspecs/", 1, "", "");




#
# Files for the documentation subpackage
#
	add_files_rule("^\\/usr\\/share\\/gtk\-doc\\/html\\/[a-z0-9A-Z\\_\\-\\.]+\\/.\*", 2, 
		       "(\\/usr\\/share\\/gtk\-doc\\/html\\/[a-z0-9A-Z\\_\\-\\.]+\\/).\*", "\*");
	add_files_rule("^\\/usr\\/share\\/doc\\/[a-zA-Z0-9\-]*", 2, 
                       "(\\/usr\\/share\\/doc\\/[a-zA-Z0-9\-]+\\/).*", "\*");
	add_files_rule("^\\/usr\\/share\\/man\\/man[0-9]\\/[a-zA-Z0-9\-]*", 2, 
                       "(\\/usr\\/share\\/man\\/man[0-9]\\/[a-zA-Z0-9\-]+\\/).*", "\*");
	add_files_rule("^\\/usr\\/share\\/gnome\\/help\\/", 2, 
			"(\\/usr\\/share\\/gnome\\/help\\/.*?\\/.*?\\/).*", "\*");
		       
		       
#
# Files to just not package at all (picked up by other things)
#		     
	add_files_rule("^\\/usr\\/share\\/locale", 99, "", "");
	# compiled python things will get auto cleaned by rpm
#	add_files_rule("\.pyo\$", 99, "", "");
#	add_files_rule("\.pyc\$", 99, "", "");

}

sub apply_files_rules
{
	my $filenumber = @allfiles;
	
	if ($filenumber == 0) {
		return;
	}
	
	while (@allfiles > 0) {
		my $filename = $allfiles[0];
		my $destname = $filename;
		my $handled = 0;
	
#
# while we're here, try to guess what group our package is
#	
		guess_group_from_file($filename);
	
		foreach (@files_match) {
			my $match = $_;
			
			if ($filename =~ /$match/) {				
#
# First try to see if we can turn the full filename into a
# wildcard based filename
#
				if (defined($files_from{$match}) && defined($files_to{$match})) {
					$from = $files_from{$match};
					$to = $files_to{$match};
					$destname =~ s/$from/$1$to/;
#					print "changing $filename to $destname\n";
				}

# devel package
				if ($files_target{$match} == 1) {
					$handled = 1;
					push(@develfiles, $destname);
				}
# doc rules.. also prepend %doc
				if ($files_target{$match} == 2) {
					$handled = 1;
					$destname = "\"%doc " . $destname . "\"";
					push(@docfiles, $destname);
					$totaldocs = $totaldocs + 1;
				}
# don't package
				if ($files_target{$match} == 99) {
					$handled = 1;
					if ($filename =~ /\/usr\/share\/locale\/.*?\/LC_MESSAGES\/(.*)\.mo/) {
						$localename = $1;
					}
				}
			}
		}
		

#
# if the destination name contains our package version,
# use %version instead for future maintenance
#
		$destname =~ s/$version/\%\{version\}/g;	
		if ($handled == 0) {
			push(@mainfiles, $destname);
		}	
		shift(@allfiles);
	}
	
#
# Now.. if we have less than 5 documentation files, just stick them in the main package
#

	$filenumber = @docfiles;
	
	if ($filenumber <= 5) {
		while (@docfiles > 0) {
			my $filename = $docfiles[0];
	
			push(@mainfiles, $filename);
			shift(@docfiles);
		}
	}
	
}

sub print_files
{
	my $count = @mainfiles;
	if ($count == 0) {
		return;
	}

	# remove dupes
	undef %saw;
	@saw{@mainfiles} = ();
    	@out = sort keys %saw;

	print OUTFILE "Files:\n";
	foreach (@out) {
		print OUTFILE "    - $_\n";
	}
}

sub print_devel
{
	my $count = @develfiles;
	if ($count == 0) {
		return;
	}
	print OUTFILE "SubPackages:\n";
	$printed_subpackages = 1;
	print OUTFILE "    - Name: devel\n";
	print OUTFILE "      Summary: Development components for the $name package\n";
	print OUTFILE "      Group: Development/Libraries\n";
	print OUTFILE "      Description:\n";
	print OUTFILE "         - Development files for the $name package\n";

	# remove dupes
	undef %saw;
	@saw{@develfiles} = ();
    	@out = sort keys %saw;

	print OUTFILE "      Files:\n";
	foreach (@out) {
		print OUTFILE "        - $_\n";
	}                
}

sub print_doc
{
	my $count = @docfiles;
	if ($count == 0) {
		return;
	}
	if ($printed_subpackages == 0) {
		print OUTFILE "SubPackages:\n";
		$printed_subpackages = 1;
	}
	print OUTFILE "    - Name: docs\n";
	print OUTFILE "      Summary: Documentation components for the $name package\n";
	print OUTFILE "      Group: Documentation\n";

	# remove dupes
	undef %saw;
	@saw{@docfiles} = ();
    	@out = sort keys %saw;

	print OUTFILE "      Files:\n";
	foreach (@out) {
		print OUTFILE "        - $_\n";
	}                
}


# end of %files section
#
######################################################################


######################################################################
#
# What we can learn from configure.ac/configure
#
# - pkgconfig requirements
# - regular build requirements
# - package name / version


sub setup_pkgconfig_ban
{
        push(@banned_pkgconfig, "^dnl\$");
        push(@banned_pkgconfig, "^hal\$"); # we don't have nor want HAL
        push(@banned_pkgconfig, "tslib-0.0"); # we don't want tslib-0.0 (legacy touchscreen interface)
        push(@banned_pkgconfig, "intel-gen4asm");
        push(@banned_pkgconfig, "^xp\$");  # xprint - deprecated and not in meego
        push(@banned_pkgconfig, "^directfb\$");  # we use X, not directfb
        push(@banned_pkgconfig, "^gtkmm-2.4\$");  # we use X, not directfb
        push(@banned_pkgconfig, "^evil\$");
        push(@banned_pkgconfig, "^directfb");
        push(@banned_pkgconfig, "^sdl ");
        
        
}

sub setup_failed_commands
{
        $failed_commands{"doxygen"} = "doxygen";        
        $failed_commands{"scrollkeeper-config"} = "rarian-compat";
        $failed_commands{"dot"} = "graphviz";
        $failed_commands{"flex"} = "flex";
        $failed_commands{"lex"} = "flex";
        $failed_commands{"freetype-config"} = "freetype-devel";
        $failed_commands{"makeinfo"} = "texinfo";
        $failed_commands{"desktop-file-install"} = "desktop-file-utils";
        $failed_commands{"deflateBound in -lz"} = "zlib-devel";
        $failed_commands{"gconftool-2"} = "GConf-dbus";
        $failed_commands{"jpeglib.h"} = "libjpeg-devel";
        $failed_commands{"expat.h"} = "expat-devel";
        $failed_commands{"bison"} = "bison";
        $failed_commands{"msgfmt"} = "gettext";
        $failed_commands{"curl-config"} = "libcurl-devel";
        $failed_commands{"doxygen"} = "doxygen";
        $failed_commands{"X"} = "pkgconfig(x11)";

        $failed_commands{"gawk"} = "gawk";
        $failed_commands{"xbkcomp"} = "xkbcomp";
        $failed_commands{"Vorbis"} = "libvorbis-devel";
        # checking Expat 1.95.x... no
        $failed_commands{"Expat 1.95.x"} = "expat-devel";
        $failed_commands{"xml2-config path"} =  "libxml2-devel";

        $failed_libs{"-lz"} = "zlib-devel";
        $failed_libs{"-lncursesw"} = "ncurses-devel";
        $failed_libs{"-ltiff"} = "libtiff-devel";
        $failed_libs{"-lasound"} = "alsa-lib-devel";
        $failed_libs{"Curses"} = "ncurses-devel";
        
        $failed_headers{"X11/extensions/randr.h"} = "xrandr";
        $failed_headers{"X11/Xlib.h"} = "x11";
        $failed_headers{"X11/extensions/XShm.h"} = "xext";
        $failed_headers{"X11/extensions/shape.h"} = "xext";
        $failed_headers{"ncurses.h"} = "ncursesw";
        $failed_headers{"curses.h"} = "ncursesw";
        $failed_headers{"pci/pci.h"} = "libpci";
        $failed_headers{"xf86.h"} = "xorg-server";
        $failed_headers{"sqlite.h"} = "sqlite3";
        
        $failed_headers{"X11/extensions/XIproto.h"} = "xi";
        $failed_headers{"QElapsedTimer"} = "";
}



my @package_configs;
my @buildreqs;
my $uses_configure = 0;


sub push_pkgconfig_buildreq
{
	my ($pr) = @_;

	$pr =~ s/\s+//g;
	
	# remove collateral ] ) etc damage in the string
	$pr =~ s/\"//g;
	$pr =~ s/\)//g;
	$pr =~ s/\]//g;
	$pr =~ s/\[//g;


	# first, undo the space packing

	$pr =~ s/\>\=/ \>\= /g;
	$pr =~ s/\<\=/ \<\= /g;

	$pr =~ s/\<1.1.1/  /g;
	
	# don't show configure variables, we can't deal with them
	if ($pr =~ /^\$/) {
		return;
	}
	if ($pr =~ /AC_SUBST/) {
		return;
	}
	
	
	

	# process banned pkgconfig options for things that we don't
	# have or don't want.
	
	
	# remore versions that are macros or strings, not numbers
	$pr =~ s/\s\>\= \$.*//g;

	$pr =~ s/\s\>\= [a-zA-Z]+.*//g;

	# don't show configure variables, we can't deal with them
	if ($pr =~ /\$/) {
		return;
	}

	foreach (@banned_pkgconfig) {
	        my $ban = $_;
	        if ($pr =~ /$ban/) {
	                return;
	        }
	}
	
	push(@package_configs, $pr);
}

#
# detect cases where we require both a generic pkgconfig, and a version specific
# case
#
sub uniquify_pkgconfig
{
        # first remove real dupes
        undef %saw;
        @saw{@package_configs} = ();
        @out = sort keys %saw;
        
        my $count = 0;
                                        
        while ($count < @out) {

                my $entry = $out[$count];
                
                foreach(@out) {
                        my $compare = $_;
                        if ($entry eq $compare) {
                                next;
                        }
                        
                        $compare =~ s/ \>\=.*//g;
                        if ($entry eq $compare) {
                                $out[$count] = "";
                        }
                }
                $count = $count + 1;
        }
        @package_configs = @out;
}


sub process_configure_ac
{
	my ($filename) = @_;
	my $line = "";
	my $depth = 0;
	my $keepgoing = 1;
	my $buffer = "";

	if (!-e $filename)  {
		return;
	}
	
	$uses_configure = 1;



	open(CONFIGURE, "$filename") || die "Couldn't open $filename\n";
        seek(CONFIGURE, 0,0) or die "seek : $!";	
	while ($keepgoing && !eof(CONFIGURE)) {
                $buffer = getc(CONFIGURE);
                
		if ($buffer eq "(") {
			$depth = $depth + 1;
		}
		if ($buffer eq ")" && $depth > 0) {
			$depth = $depth - 1;
		}
		
		if (!($buffer eq "\n")) {
			$line = $line . $buffer;
		}
		
		if (!($buffer eq "\n") || $depth > 0) {
			redo unless eof(CONFIGURE);
		}
		
		if ($line =~ /PKG_CHECK_MODULES\((.*)\)/) {
			my $match = $1;
			$match =~ s/\s+/ /g;
			$match =~ s/, /,/g;
			my @pkgs = split(/,/, $match);
			my $pkg;
			if (defined($pkgs[1])) {
				$pkg = $pkgs[1];
			} else {
				next;
			}
			if ($pkg =~ /\[(.*)\]/) {
				$pkg = $1;
			}

			$pkg =~ s/\s+/ /g;
			# deal with versioned pkgconfig's by removing the spaces around >= 's 
			$pkg =~ s/\>\=\s/\>\=/g;
			$pkg =~ s/\s\>\=/\>\=/g;
			$pkg =~ s/\=\s/\=/g;
			$pkg =~ s/\s\=/\=/g;
			$pkg =~ s/\<\=\s/\<\=/g;
			$pkg =~ s/\<\s/\</g;
			$pkg =~ s/\s\<\=/\<\=/g;
			$pkg =~ s/\s\</\</g;

			@words = split(/ /, $pkg);
			foreach(@words) {
				push_pkgconfig_buildreq($_);
			}
		}

		if ($line =~ /PKG_CHECK_EXISTS\((.*)\)/) {
			my $match = $1;
			$match =~ s/\s+/ /g;
			$match =~ s/, /,/g;
			my @pkgs = split(/,/, $match);
			my $pkg = $pkgs[0];
			if ($pkg =~ /\[(.*)\]/) {
				$pkg = $1;
			}

			$pkg =~ s/\s+/ /g;
			# deal with versioned pkgconfig's by removing the spaces around >= 's 
			$pkg =~ s/\>\=\s/\>\=/g;
			$pkg =~ s/\s\>\=/\>\=/g;
			$pkg =~ s/\<\=\s/\<\=/g;
			$pkg =~ s/\<\s/\</g;
			$pkg =~ s/\s\<\=/\<\=/g;
			$pkg =~ s/\s\</\</g;
			$pkg =~ s/\=\s/\=/g;
			$pkg =~ s/\s\=/\=/g;

			@words = split(/ /, $pkg);
			foreach(@words) {
				push_pkgconfig_buildreq($_);
			}
		}

		if ($line =~ /XDT_CHECK_PACKAGE\(.*?,.*?\[(.*?)\].*\)/) {
			my $pkg = $1;

			$pkg =~ s/\s+/ /g;
			# deal with versioned pkgconfig's by removing the spaces around >= 's 
			$pkg =~ s/\>\=\s/\>\=/g;
			$pkg =~ s/\s\>\=/\>\=/g;
			$pkg =~ s/\=\s/\=/g;
			$pkg =~ s/\s\=/\=/g;

			@words = split(/ /, $pkg);
			foreach(@words) {
				push_pkgconfig_buildreq($_);
			}
		}

		if ($line =~ /XDT_CHECK_OPTIONAL_PACKAGE\(.*?,.*?\[(.*?)\].*\)/) {
			my $pkg = $1;

			$pkg =~ s/\s+/ /g;
			# deal with versioned pkgconfig's by removing the spaces around >= 's 
			$pkg =~ s/\>\=\s/\>\=/g;
			$pkg =~ s/\s\>\=/\>\=/g;
			$pkg =~ s/\=\s/\=/g;
			$pkg =~ s/\s\=/\=/g;

			@words = split(/ /, $pkg);
			foreach(@words) {
				push_pkgconfig_buildreq($_);
			}
		}

		if ($line =~ /AC_CHECK_LIB\(\[expat\]/) {
			push(@buildreqs, "expat-devel");
		}
		if ($line =~ /AC_CHECK_FUNC\(\[tgetent\]/) {
			push(@buildreqs, "ncurses-devel");
		}
		if ($line =~ /_PROG_INTLTOOL/) {
			push(@buildreqs, "intltool");
		}
		if ($line =~ /GETTEXT_PACKAGE/) {
			push(@buildreqs, "gettext");
		}
		if ($line =~ /GTK_DOC_CHECK/) {
			push_pkgconfig_buildreq("gtk-doc");
		}
		if ($line =~ /GNOME_DOC_INIT/) {
			 push(@buildreqs, "gnome-doc-utils");
		}
		if ($line =~ /AM_GLIB_GNU_GETTEXT/) {
			push(@buildreqs, "gettext");
		}

		if ($line =~ /AC_INIT\((.*)\)/) {
			my $match = $1;
			$match =~ s/\s+/ /g;
			@acinit = split(/,/, $match);
#			$name = $acinit[0];
			
			if ($name =~ /\[(.*)\]/) {
#				$name = $1;
			}
			
			if (defined($acinit[3])) {
#				$name = $acinit[3];
				if ($name =~ /\[(.*)\]/) {
#					$name = $1;
				}
			}
			if (defined($acinit[1]) and $version eq $predef_version) {
				my $ver = $acinit[1];
				$ver =~ s/\[//g;
				$ver =~ s/\]//g;
				if ($ver =~ /\$/){} else {
					$version = $ver;
					$version =~ s/\s+//g;
				}
			}
		}
		if ($line =~ /AM_INIT_AUTOMAKE\((.*)\)/) {
			my $match = $1;
			$match =~ s/\s+/ /g;
			@acinit = split(/,/, $match);
#			$name = $acinit[0];
			
			if ($name =~ /\[(.*)\]/) {
#				$name = $1;
			}
			
			if (defined($acinit[3])) {
#				$name = $acinit[3];
				if ($name =~ /\[(.*)\]/) {
#					$name = $1;
				}
			}
			if (defined($acinit[1]) and $version eq $predef_version) {
				my $ver = $acinit[1];
				$ver =~ s/\[//g;
				$ver =~ s/\]//g;
				if ($ver =~ /\$/){} else {
					$version = $ver;
					$version =~ s/\s+//g;
				}
			}
		}
		
		$line = "";
	}
	close(CONFIGURE);
}

sub process_qmake_pro
{
	my ($filename) = @_;
	my $line = "";
	my $depth = 0;
	my $keepgoing = 1;
	my $buffer = "";
	my $prev_char = "";

	if (!-e $filename)  {
		return;
	}
	

	open(CONFIGURE, "$filename") || die "Couldn't open $filename\n";
        seek(CONFIGURE, 0,0) or die "seek : $!";	
	while ($keepgoing && !eof(CONFIGURE)) {
                $buffer = getc(CONFIGURE);
                
		if ($buffer eq "(") {
			$depth = $depth + 1;
		}
		if ($buffer eq ")" && $depth > 0) {
			$depth = $depth - 1;
		}
		
		if (!($buffer eq "\n")) {
			$line = $line . $buffer;
		}
		
		if (!($buffer eq "\n") || ($prev_char eq "\\") ) {
		        $prev_char = $buffer;
			redo unless eof(CONFIGURE);
		}
		$prev_char = " ";
		
		if ($line =~ /PKGCONFIG.*?\=(.*)/) {
		        my $l = $1;
		        my @pkgs;
		        
                        $l =~ s/\\//g;
                        $l =~ s/\s/ /g;
                        @pkgs = split(/ /, $l);
                        foreach (@pkgs) {
                                if (length($_)>1) {
                                        push_pkgconfig_buildreq($_);
                                }
                        }
		}

		$line = "";
	}
	close(CONFIGURE);
}

#
# We also check configure if it exists, it's nice for some things
# because various configure.ac macros have been expanded for us already.
#
sub process_configure
{
	my ($filename) = @_;
	my $line = "";
	my $depth = 0;
	my $keepgoing = 1;

	if (!-e $filename)  {
		return;
	}
	
	$uses_configure = 1;

	open(CONFIGURE, "$filename") || die "Couldn't open $filename\n";
        seek(CONFIGURE, 0,0) or die "seek : $!";	
	while ($keepgoing && !eof(CONFIGURE)) {
                $buffer = getc(CONFIGURE);
		
		if ($buffer eq "(") {
			$depth = $depth + 1;
		}
		if ($buffer eq ")" && $depth > 0) {
			$depth = $depth - 1;
		}
		
		if (!($buffer eq "\n")) {
			$line = $line . $buffer;
		}
		
		if (!($buffer eq "\n") || $depth > 0) {
			redo unless eof(CONFIGURE);
		}
		
		

		if ($line =~ /^PACKAGE_NAME=\'(.*?)\'/) {
			$name = $1;
		}
		if ($line =~ /^PACKAGE_TARNAME=\'(.*?)\'/) {
			$name = $1;
		}
		if ($line =~ /^PACKAGE_VERSION=\'(.*?)\'/) {
			$version = $1;
			$version =~ s/\s+//g;
		}
		if ($line =~ /^PACKAGE_URL=\'(.*?)\'/) {
			if (length($1) > 2) {
				$url = $1;
			}
		}
		

		$line = "";
	}
	close(CONFIGURE);
}

sub print_pkgconfig
{
	my $count = @package_configs;
	if ($count == 0) {
		return;
	}

	uniquify_pkgconfig();
	
	print OUTFILE "PkgConfigBR:\n";
	foreach (@out) {
		$line = $_;
		$line =~ s/^\s+//g;
		if (length($line) > 1) {
			print OUTFILE "    - $line\n";
		}
	}
}

sub print_buildreq
{
	my $count = @buildreqs;
	if ($count == 0) {
		return;
	}

	# remove dupes
	undef %saw;
	@saw{@buildreqs} = ();
    	@out = sort keys %saw;

	print OUTFILE "PkgBR:\n";
	foreach (@out) {
		print OUTFILE "    - $_\n";
	}
}


# end of configure section
#
######################################################################


######################################################################
#
# Guessing the Description and Summary for a package
#
# We'll look at various sources of information for this:
# - spec files in the package
# - debain files in the package
# - DOAP files in the package
# - pkgconfig files in the package
# - the README file in the package
# - freshmeat.net online
#

sub guess_description_from_spec {
	my ($specfile) = @_;

	my $state = 0;
	my $cummul = "";
	
	open(SPEC, $specfile);
	while (<SPEC>) {
		my $line = $_;
		if ($state == 1 && $line =~ /^\%/) {
			$state = 2;
		}
		if ($state == 1) {
			$cummul = $cummul . $line;
		}
		if ($state==0 && $line =~ /\%description/) {
			$state = 1;
		}

		if ($line =~ /Summary:\s*(.*)/ && length($summary) < 2) {
			$summary = $1;
		}
		if ($line =~ /URL:\s*(.*)/ && length($url) < 2) {
			$url = $1;
		}
	}
	close(SPEC);
	if (length($cummul) > 4) {
		$description = $cummul;
	}
}

#
# DOAP is a project to create an XML/RDF vocabulary to describe software projects, and in particular open source.
# so if someone ships a .doap file... we can learn from it.
#
sub guess_description_from_doap {
	my ($doapfile) = @_;

	open(DOAP, $doapfile);
	while (<DOAP>) {
		my $line = $_;
		# <shortdesc xml:lang="en">Virtual filesystem implementation for gio</shortdesc>
		if ($line =~ /\<shortdesc .*?\>(.*)\<\/shortdesc\>/) {
			$summary = $1;
		}
		if ($line =~ /\<homepage .*?resource=\"(.*)\"\s*\/>/) {
			$url = $1;
		}
	}
	close(DOAP);
}

#
# Debian control files have some interesting fields we can glean information
# from as well.
#
sub guess_description_from_debian_control {
	my ($file) = @_;

	my $state = 0;
	my $cummul = "";

	$file = $file . "/debian/control";
	
	open(FILE, $file) || return;
	while (<FILE>) {
		my $line = $_;
		if ($state == 1 && length($line) < 2) {
			$state = 2;
		}
		if ($state == 1) {
			$cummul = $cummul . $line;
		}
		if ($state==0 && $line =~ /\Description: (.*)/) {
			$state = 1;
			$cummul = $1;
		}

	}
	close(FILE);
	if (length($cummul) > 4) {
		$description = $cummul;
	}
}

#
# the pkgconfig files have often a one line description
# of the software... good for Summary
#
sub guess_description_from_pkgconfig {
	my ($file) = @_;

	open(FILE, $file);
	while (<FILE>) {
		my $line = $_;

		if ($line =~ /Description:\s*(.*)/ && length($summary) < 2) {
			$summary = $1;
		}
	}
	close(FILE);
}

#
# Freshmeat can provide us with a good one paragraph description
# of the software..
#
sub guess_description_from_freshmeat {
	my ($tarname) = @_;
	my $cummul = "";
	my $state = 0;
	open(HTML, "curl -s http://freshmeat.net/projects/$tarname |");
	while (<HTML>) {
		my $line = $_;

		if ($state == 1) {
			$cummul = $cummul . $line;
		}
		if ($state == 0 && $line =~ /\<div class\=\"project-detail\"\>/) {
			$state = 1;
		}
		if ($state == 1 && $line =~/\<\/p\>/) {
			$state = 2;
		}
	}
	close(HTML);
	$cummul =~ s/\<p\>//g;
	$cummul =~ s/\r//g;
	$cummul =~ s/\<\/p\>//g;
	$cummul =~ s/^\s*//g;
	if (length($cummul)>10) {
		$description = $cummul;
	}
}
#
# If all else fails, just take the first paragraph of the
# readme file
#
sub guess_description_from_readme {
	my ($file) = @_;

	my $state = 0;
	my $cummul = "";
	
	open(FILE, $file);
	while (<FILE>) {
		my $line = $_;
		if ($state == 1 && $line =~ /^\n/ && length($cummul) > 80) {
			$state = 2;
		}
		if ($state == 0 && length($line)>1) {
			$state = 1;
		}
		if ($state == 1) {
			$cummul = $cummul . $line;
		}
		if ($line =~ /(http\:\/\/.*$name.*\.org)/) {
			my $u = $1;
			if ($u =~ /bug/ || length($url) > 1) {
			} else {
				$url = $u;
			}
		}
	}
	close(FILE);
	if (length($cummul) > 4 && length($description)<3) {
		$description = $cummul;
	}
}

#
# Glue all the guesses together
#
sub guess_description {
	my ($directory) = @_;


	@files = <$directory/README*>;
	foreach (@files) {
		guess_description_from_readme($_);
	}

	if (length($name)>2) {
		guess_description_from_freshmeat($name);
	}

	@files = <$directory/*.spec*>;
	foreach (@files) {
		guess_description_from_spec($_);
	}

	guess_description_from_debian_control($directory);

	$name =~ s/ //g;
	@files = <$directory/$name.pc*>;
	foreach (@files) {
		guess_description_from_pkgconfig($_);
	}
	@files = <$directory/*.pc.*>;
	foreach (@files) {
		guess_description_from_pkgconfig($_);
	}
	@files = <$directory/*.pc>;
	foreach (@files) {
		guess_description_from_pkgconfig($_);
	}
	@files = <$directory/*.doap>;
	foreach (@files) {
		guess_description_from_doap($_);
	}

	if (length($summary) < 2) {
		$summary = $description;
		$summary =~ s/\n/ /g;
		$summary =~ s/\s+/ /g;
		if ($summary =~ /(.*?)\./) {
			$summary = $1;
		}
	}

}

# end of Description / Summary section
#
######################################################################



#
# Build the package, and wait for rpm to complain about unpackaged
# files.... which we then use as basis for our %files section
#
sub guess_files_from_rpmbuild {
	my $infiles = 0;
	open(OUTPUTF, "rpmbuild --nodeps --define \"\%_sourcedir $orgdir \" -ba $name.spec 2>&1 |");
	while (<OUTPUTF>) {
		my $line2 = $_;

		if ($infiles == 1 && $line2  =~ /RPM build errors/) {
		        $infiles = 2;
		}
		if ($infiles == 1 && $line2  =~ /^Building/) {
		        $infiles = 2;
		}
		
		if ($infiles == 1) {
			$line2 =~ s/\s*//g;
			push(@allfiles, $line2);
		}
		if ($line2 =~ /    Installed \(but unpackaged\) file\(s\) found\:/) {
			$infiles = 1;
		}
	}
	close(OUTPUTF);
	if (@allfiles == 0) {
		print "Build failed ... stopping here.\n";
		exit(0);
	}

}

sub guess_files_from_oscbuild {
	my $infiles = 0;
	my $restart = 0;	
	my $mustrestart = 0;
        my $rcount = 0;
        my $done_python = 0;
        
        system("osc addremove &> /dev/null");
	system("osc ci -m \"Initial import by autospectacle\" &> /dev/null");

retry: 
        if ($restart > 0) {
                write_yaml();
                print "Restarting the build\n";
        }
        $restart = 0;
        $infiles = 0;
        $mustrestart = 0;
	open(OUTPUTF, "osc build --no-verify $name.spec 2>&1 |");
	while (<OUTPUTF>) {
		my $line2 = $_;
		
#		print "line is $line2\n";
		if ($infiles == 1 && $line2  =~ /RPM build errors/) {
		        $infiles = 2;
		}
		if ($infiles == 1 && $line2  =~ /^Building/) {
		        $infiles = 2;
		}
		if ($infiles == 1) {
			$line2 =~ s/\s*//g;
			push(@allfiles, $line2);
		}
		if ($line2 =~ /No package \'(.*)\' found/) {
                        push_pkgconfig_buildreq("$1");       
                        $restart = $restart + 1;
                        print "    Adding pkgconfig($1) requirement\n";
		}
		if ($line2 =~ /Package requirements \((.*?)\) were not met/) {
		        $pkg = $1;
			# deal with versioned pkgconfig's by removing the spaces around >= 's 
			$pkg =~ s/\>\=\s/\>\=/g;
			$pkg =~ s/\s\>\=/\>\=/g;
			$pkg =~ s/\=\s/\=/g;
			$pkg =~ s/\s\=/\=/g;
		        my @req = split(/ /,$pkg);
                        foreach (@req) {
                                push_pkgconfig_buildreq("$_");       
                                
                                $restart = $restart + 1;
                                print "    Adding pkgconfig($_) requirement\n";
                        }
		}
		if ($line2 =~ /which: no qmake/) {
		        $restart += 1;
                        push_pkgconfig_buildreq("Qt");
                        print "    Adding Qt requirement\n";
		}
		if ($line2 =~ /Cannot find development files for any supported version of libnl/) {
		        $restart += 1;
                        push_pkgconfig_buildreq("libnl-1");
                        print "    Adding libnl requirement\n";
		}
		if ($line2 =~ /<http:\/\/www.cmake.org>/) {
		        $restart += 1;
                        push(@buildreqs, "cmake");
                        print "    Adding cmake requirement\n";
		}
		if ($line2 =~ /checking for (.*?)\.\.\. not_found/ || $line2 =~ /checking for (.*?)\.\.\. no/  || $line2 =~ /checking (.*?)\.\.\. no/) {
		        $pkg = $1;
                        while (($key,$value) = each %failed_commands) {
                                if ($pkg eq $key) {
                                        push(@buildreqs, $value);
                                        print "    Adding $value requirement\n";
                                        $restart += $restart + 1;
                                        $mustrestart = 1;
                                }
                        }
                        
		}

		if ($line2 =~ /checking for [a-zA-Z0-9\_]+ in (.*?)\.\.\. no/) {
		        $pkg = $1;
                        while (($key,$value) = each %failed_libs) {
                                if ($pkg eq $key) {
                                        push(@buildreqs, $value);
                                        print "    Adding $value requirement\n";
                                        $restart += $restart + 1;
                                        $mustrestart = 1;
                                }
                        }
                        
		}

		if ($line2 =~ /-- Could NOT find ([a-zA-Z0-9]+)/) {
		        $pkg = $1;
                        while (($key,$value) = each %failed_libs) {
                                if ($pkg eq $key) {
                                        push(@buildreqs, $value);
                                        print "    Adding $value requirement\n";
                                        $restart += $restart + 1;
                                        $mustrestart = 1;
                                }
                        }
                        
		}

		if ($line2 =~ /fatal error\: (.*)\: No such file or directory/) {
		        $pkg = $1;
                        while (($key,$value) = each %failed_headers) {
                                if ($pkg eq $key) {
                                        push_pkgconfig_buildreq($value);
                                        print "    Adding $value requirement\n";
                                        $restart += $restart + 1;
                                }
                        }
                        
		}
		if ($line2 =~ /checking for UDEV\.\.\. no/) {
		        print "    Adding pkgconfig(udev) requirement\n";
		        push_pkgconfig_buildreq("udev");
		}
		if ($line2 =~ /checking for Apache .* module support/) {
		        print "    Adding pkgconfig(httpd-devel) requirement\n";
		        push(@buildreqs, "httpd-devel");
		        if ($rcount < 3) {
		                $restart = $restart + 1;
		        }
		}
		if ($line2 =~ /([a-zA-Z0-9\-\_]*)\: command not found/i) {
		        my $cmd = $1;
		        my $found = 0;
		        
                        while (($key,$value) = each %failed_commands) {
                                if ($cmd eq $key) {
                                        push(@buildreqs, $value);
                                        print "    Adding $value requirement\n";
                                        $restart += $restart + 1;
                                        $mustrestart = 1;
                                        $found = 1;
                                }
                        }
                        
                        if ($found < 1) {
                                print "    Command $cmd not found!\n";
                        }
		}
		if ($line2 =~ /checking for.*in -ljpeg... no/) {
                        push(@buildreqs, "libjpeg-devel");
                        print "    Adding libjpeg-devel requirement\n";
                        $restart = $restart + 1;
		}
		if ($line2 =~ /fatal error\: zlib\.h\: No such file or directory/) {
                        push(@buildreqs, "zlib-devel");
                        print "    Adding zlib-devel requirement\n";
                        $restart = $restart + 1;
		}
		if ($line2 =~ /error\: xml2-config not found/) {
                        push_pkgconfig_buildreq("libxml-2.0");
                        print "    Adding libxml2-devel requirement\n";
                        $restart = $restart + 1;
		}
		if ($line2 =~ /checking \"location of ncurses\.h file\"/) {
                        push(@buildreqs, "ncurses-devel");
                        print "    Adding ncurses-devel requirement\n";
                        $restart = $restart + 1;
		}
		if (($line2 =~ / \/usr\/include\/python2\.6$/ || $line2 =~ / to compile python extensions/) && $done_python == 0) {
                        push(@buildreqs, "python-devel");
                        print "    Adding python-devel requirement\n";
                        $restart = $restart + 1;
                        $done_python = 1;
		}
		if ($line2 =~ /error: must install xorg-macros 1.6/) {
                        push_pkgconfig_buildreq("xorg-macros");
                        print "    Adding xorg-macros requirement\n";
                        $restart = $restart + 1;
		}
		if ($line2 =~ /installing .*?.gmo as [a-zA-Z0-9\-\.\/\_]+?\/([a-zA-Z0-9\-\_\.]+)\.mo$/) {
		        my $loc = $1;
		        if ($loc eq $localename) {} else {
		                print "    Changing localename from $localename to $loc\n";
        		        $localename = $loc;
                                $restart = $restart + 1;
                        }
		}
		
		if ($infiles == 0 && $line2 =~ /    Installed \(but unpackaged\) file\(s\) found\:/) {
			$infiles = 1;
		}
	}
	close(OUTPUTF);
	if (@allfiles == 0 || $mustrestart > 0) {
	        if ($restart >= 1) 
                {
                        $rcount = $rcount + 1;
                        if ($rcount < 10) {
        	                goto retry;
                        }
	        }
		print "Build failed ... stopping here.\n";
		exit(0);
	}

}

sub process_rpmlint {
	my $infiles = 0;
		

        if ($oscmode == 0) {
                return;
        }		

        print "Verifying package   ....\n";
        
        system("osc addremove &> /dev/null");
	system("osc ci -m \"Final import by autospectacle\" &> /dev/null");

	open(OUTPUTF, "osc build --no-verify $name.spec 2>&1 |");
	while (<OUTPUTF>) {
		my $line2 = $_;
		
#		print "line is $line2\n";
		if ($infiles == 1 && $line2  =~ /RPM build errors/) {
		        $infiles = 2;
		}
		if ($infiles == 1 && $line2  =~ /^Building/) {
		        $infiles = 2;
		}
		if ($infiles == 1) {
			$line2 =~ s/\s*//g;
			push(@allfiles, $line2);
		}
		if ($infiles == 0 && $line2 =~ /    Installed \(but unpackaged\) file\(s\) found\:/) {
			$infiles = 1;
		}
	}
	close(OUTPUTF);

}

sub guess_name_from_url {
	my ($bigurl) = @_;
	
	@spliturl = split(/\//, $bigurl);
	while (@spliturl > 1) {
		shift(@spliturl);
	}
	my $tarfile = $spliturl[0];
	
	# Ensure correct name resolution from .zip&tgz archives
	$tarfile =~ s/\.zip/\.tar/;
	$tarfile =~ s/\.tgz/\.tar/;
	$tarfile =~ s/\_/\-/g;
	if ($tarfile =~ /(.*?)\-([0-9\.\-\~]+.*?)\.tar/) {
		$name = $1;
		$version = $2;
		$version =~ s/\-/\_/g;
	}
}

############################################################################
#
# Output functions
#

sub print_name_and_description
{
	my @lines;

	print OUTFILE "Name       : $name\n";
	print OUTFILE "Version    : $version\n";
	print OUTFILE "Release    : 1\n";
	
	# remove dupes
	undef %saw;
	@saw{@groups} = ();
    	@out = sort keys %saw;

    	if (@out == 1) {
		foreach (@out) {
			print OUTFILE "Group      : $_\n";
		}
	} else {
		print OUTFILE "Group      : $group\n";
	}
	# 
	# Work around spectacle bug
	$summary =~ s/\:\s/ /g;
	$summary =~ s/^([a-z])/\u$1/ig; 
	$summary =~ s/\@//g; 
	$summary = substr($summary, 0, 79);
	
	$summary =~ s/\.^//g;
	if (length($summary) < 1) {
	        $summary = "TO BE FILLED IN";
	}
	#
	print OUTFILE "Summary    : $summary\n";
	print OUTFILE "Description: |\n";

	$description =~ s/&quot;/\"/g;
	$description =~ s/\@//g; 
	@lines = split(/\n/, $description);
	foreach (@lines) {
		print OUTFILE "    $_\n";
	}
	if (length($url)>1) {
		print OUTFILE "URL        : $url\n";
	}

	# remove dupes
	undef %saw;
	@saw{@sources} = ();
    	@out = sort keys %saw;

	print OUTFILE "Sources    : \n";
	foreach (@out) {
		$source = $_;
		$source =~ s/$version/\%\{version\}/g;	

		print OUTFILE "    - $source\n";
	}
	
        if (@patches > 0) {
                print OUTFILE "Patches: \n";
                foreach (@patches) {
                        my $patch = $_;
        		print OUTFILE "    - $patch\n";
                }
        }
	
	print OUTFILE "\n";
	if (length($configure)>2) {
		print OUTFILE "Configure  : $configure\n";
	}
	if (length($localename) > 2) {
		print OUTFILE "LocaleName : $localename\n";
	}
	if (length($builder) > 2) {
	        print OUTFILE "Builder    : $builder\n";
	}
}

sub write_makefile
{
	open(MAKEFILE, ">Makefile");

	print MAKEFILE "PKG_NAME := $name\n";
	print MAKEFILE "SPECFILE = \$(addsuffix .spec, \$(PKG_NAME))\n";
	print MAKEFILE "YAMLFILE = \$(addsuffix .yaml, \$(PKG_NAME))\n";
	print MAKEFILE "\n";
	print MAKEFILE "include /usr/share/packaging-tools/Makefile.common\n";
	
	close(MAKEFILE);
}

sub write_changelog
{
	open(CHANGELOG, ">$name.changes");
	$date = ` date +"%a %b %d %Y"`;	
	chomp($date);
	print CHANGELOG "* $date - Autospectacle <autospectacle\@meego.com> - $version\n";
	print CHANGELOG "- Initial automated packaging\n";
	close(CHANGELOG);
}

sub write_yaml
{
	open(OUTFILE, ">$name.yaml");
	print_name_and_description();
	print_license();
	print_pkgconfig();
	print_buildreq();
	print_files();
	print_devel();
	print_doc();
	close(OUTFILE);

	write_makefile();
	write_changelog();

	system("rm $name.spec 2>/dev/null");
	system("specify &> /dev/null");
	if ($oscmode > 0) {
	        system("osc addremove");
        	system("osc ci -m \"Import by autospectacle\" &> /dev/null");
        }

}

sub write_bbfile
{
	my $curdir = `pwd`;
	chomp($curdir);

	if ($python == 1) {
	    $name =~ s/python-//;
    	    $name = lc("python-" . $name);	    
	}
	
	if (-e "$curdir/${name}_$version.bb") {
	    print "Wont overwrite file:";
	    print "$curdir/${name}_$version.bb, exiting\n";
	    return;
	}
	open(BBFILE, ">${name}_$version.bb");
	
	print BBFILE "SUMMARY = \"$summary\"\n";
	print BBFILE "DESCRIPTION = \"$description\"\n";
	print BBFILE "HOMEPAGE = \"$homepage\"\n";

	if ($python == 1) {
	    print BBFILE "SRCNAME = \"$summary\"\n";
	}

	print BBFILE "LICENSE = \"@license\"\n";
	print BBFILE "LIC_FILES_CHKSUM = \"";
	foreach (keys %lic_files) {
		print BBFILE "file://" . basename($_) . ";md5=$lic_files{$_} \\\n";
	}
	print BBFILE "\"\n\n";

	if (@license <= 0) {
		print "Can NOT get license from package source files.\n";
		print "Please update the LICENSE and LIC_FILES_CHKSUM manually.\n";
	}

	if (@buildreqs > 0) {
		my %saw;
		my @out = grep(!$saw{$_}++,@buildreqs);
		print BBFILE "DEPENDS = \"@out\"\n\n";
	};

	if (@rdepends > 0) {
	    print BBFILE "RDEPENDS_\$\{PN\} += \"";
	    foreach (@rdepends) {
		print BBFILE "$_ \\\n\t";
	    }
	    print BBFILE "\"\n";
	}

	print BBFILE 'PR = "r0"' . "\n";
	if ($python == 1) {
	    print BBFILE "PV = \"$pversion\"\n\n";
	}

	print BBFILE "SRC_URI = \"";
	foreach (@sources) {
		print BBFILE "$_ \\\n";
	}
	print BBFILE "\"\n\n";
	print BBFILE "SRC_URI[md5sum] = \"$md5sum\"\n";
	print BBFILE "SRC_URI[sha256sum] = \"$sha256sum\"\n\n";
	if ($python == 1) {
	    print BBFILE "S = \"\${WORKDIR}/\${SRCNAME}-\${PV}\"\n";
	}

	if (@inherits) {
		print BBFILE "inherit ";
		foreach (@inherits) {
			print BBFILE "$_ ";
		}
		print BBFILE "\n";
	}

	close(BBFILE);	
	print "Create bb file: $curdir/${name}_$version.bb\n";
}

sub calculate_sums
{
    @_ = basename $dir;
    my $md5output = `md5sum @_`;
    $md5output =~ /^([a-zA-Z0-9]*) /;
    $md5sum = $1;
    chomp($md5sum);
    my $sha256output = `sha256sum @_`;
    $sha256output =~ /^([a-zA-Z0-9]*) /;
    $sha256sum = $1;
    chomp($sha256sum);
}


############################################################################
#
# Main program 
#

if ( @ARGV < 1 || $ARGV[0] eq "--help" ) {
    print "Usage: $0 [-r] <url-of-source-tarballs>\n";
    exit(1);
}

# Recusive parsing of python dependencies using
# easy_install
my $recurse_python = 0;
if ($ARGV[0] eq "-r") {
    $recurse_python = 1;
    shift @ARGV;
}

if (@ARGV > 1) {
        my $i = 1;
        while ($i < @ARGV) {
                my $patch = $ARGV[$i];
                print "Adding patch $patch\n";
                push(@patches, $patch);
                $i++;
        }
}

setup_licenses();
setup_files_rules();
setup_group_rules();
setup_pkgconfig_ban();
setup_failed_commands();

if (-e ".osc/_packages") {
 $oscmode = 1;
}

my $tmpdir = tempdir();

$dir = $ARGV[0];
guess_name_from_url($dir);
push(@sources, $dir);

#system("cd $tmpdir; curl -s -O $dir");
$orgdir = `pwd`;
chomp($orgdir);
my $outputdir = $name;
if (! $name) {
	$outputdir = basename $dir;
}
mkpath($outputdir);
chdir($outputdir);
print "Downloading package: $dir\n";
system("wget --quiet $dir") == 0 or die "Download $dir failed.";

calculate_sums($outputdir);

print "Unpacking to       : $tmpdir\n";

my @tgzfiles = <$orgdir/$outputdir/*.tgz>;
foreach (@tgzfiles) {
        my $tgz = basename $_;
        my $tar = $tgz;
        $tar =~ s/tgz/tar\.gz/g;
        $dir =~ s/tgz/tar\.gz/g;
        system("mv $orgdir/$outputdir/$tgz $orgdir/$outputdir/$tar");
        guess_name_from_url($dir);
}

#
# I really really hate the fact that meego deleted the -a option from tar.
# this is a step backwards in time that is just silly.
#

my @sourcetars = <$orgdir/$outputdir/*\.tar\.bz2 $orgdir/$outputdir/*\.tar\.gz $orgdir/$outputdir/*\.zip>;
if ( length @sourcetars == 0) {
	print "Can NOT find source tarball. Exiting...\n";
	exit (1);
}
if (defined($sourcetars[0]) and $sourcetars[0] =~ ".*\.tar\.bz2") {
	system("cd $tmpdir; tar -jxf $sourcetars[0] &>/dev/null");
} elsif (defined($sourcetars[0]) and $sourcetars[0] =~ ".*\.tar\.gz") {
	system("cd $tmpdir; tar -zxf $sourcetars[0] &>/dev/null");
} elsif (defined($sourcetars[0]) and $sourcetars[0] =~ ".*\.zip") {
        system("cd $tmpdir; unzip $sourcetars[0] &>/dev/null");
}

print "Parsing content    ....\n";
my @dirs = <$tmpdir/*>;
foreach (@dirs) {
	$dir = $_;
}

$fulldir = $dir;

if ( -e "$dir/setup.py" ) {
       	$python = 1;
	$tmp_stools = `grep -r setuptools $dir/setup.py`;
	if (length($tmp_stools) > 2) {
	    push(@inherits, "setuptools");
	} else {
	    push(@inherits, "distutils");
	}	

	$templic = `cd $dir; python setup.py --license;`;
	$templic =~ s/[\r\n]+//g;
	push(@license, $templic);
	$summary = `cd $dir; python setup.py --name`;
	$summary =~ s/[\r\n]+//g;
	$description = `cd $dir; python setup.py --description`;
	$description =~ s/[\r\n]+//g;
	$homepage = `cd $dir; python setup.py --url`;
	$homepage =~ s/[\r\n]+//g;
	$pversion = `cd $dir; python setup.py -V`;
	$pversion =~ s/[\r\n]+//g;
#	$findoutput = `cd $dir; python setup.py --requires`;
#	if (length($findoutput) < 3) {
	$findoutput = `find $dir/*.egg-info/ -name "requires.txt" 2>/dev/null`;
#	}
	@findlist = split(/\n/, $findoutput);
	foreach (@findlist) {
	    push(@rawpythondeps, `sed -e '/^\$/d' "$_" | sed '/^\\[/d'`);
	    chomp(@rawpythondeps);
	    push(@rdepends, `sed -e 's/python-//g' "$_" | sed '/^\\[/d'`);
	    chomp(@rdepends);
	    if ($recurse_python == 1) {
		foreach (@rawpythondeps) {
		    my $ptempdir = tempdir();
		    $purl = `easy_install -aeb $ptempdir "$_" 2>/dev/null`;
		    $purl =~ s/#.*//g;
		    @purllist = $purl =~ m/Downloading (.*:\/\/.*\n)/g;
		    chomp(@purllist);
		    
		    # Remove empty lines
		    @purllist = grep(/\S/, @purllist);

		    # Recursively create recipes for dependencies
		    if (@purllist != 0) {
			if (fork) {
			    # Parent, do nothing
			} else {
			    # child, execute 
			    print "Recursively creating recipe for: $purllist[0]\n";
			    exec("cd .. ; create-recipe -r $purllist[0]");
			}
		    }
		}
		wait;
	    }

	    foreach $item (@rdepends) {
		@pyclean = split(/(\=|\<|\>).*/, $item);
		if (defined($pyclean[0])) {
		    $item = lc("python-" . $pyclean[0]);
		}
	    }
	}
}

if ( -e "$dir/autogen.sh" ) {
	$configure = "autogen";
	$uses_configure = 1;
	push(@inherits, "autotools");
}
if ( -e "$dir/BUILD-CMAKE" ) {
	$configure = "cmake";
	push(@buildreqs, "cmake");
	$uses_configure = 1;
	push(@inherits, "cmake");
}

if ( -e "$dir/configure" ) {
	$configure = "";
}

my @files = <$dir/configure\.*>;

my $findoutput = `find $dir -name "configure.ac" 2>/dev/null`;
my @findlist = split(/\n/, $findoutput);
foreach (@findlist) {
	push(@files, $_);
}
foreach (@files) {
	process_configure_ac("$_");
}

$findoutput = `find $dir -name "*.pro" 2>/dev/null`;
@findlist = split(/\n/, $findoutput);
foreach (@findlist) {
	process_qmake_pro("$_");
}

if (-e "$dir/$name.pro") {
        $builder = "qmake";
        push_pkgconfig_buildreq("Qt");
	push(@inherits, "qmake2");
}

#
# This is a good place to generate configure.in
#
if (length($configure) > 2) {
	if ($configure eq "autogen") {
		system("cd $dir ; ./autogen.sh &> /dev/null");
	}
}


@files = <$dir/configure>;
foreach (@files) {
	process_configure("$_");
}

if ($uses_configure == 0) {
	$configure = "none"; 
}

@files = <$dir/docs/license.txt>;
foreach (@files) {
	guess_license_from_file("$_");
}

@files = <$dir/COPY*>;
foreach (@files) {
	guess_license_from_file("$_");
}

@files = <$dir/LICENSE*>;
foreach (@files) {
	guess_license_from_file("$_");
}


@files = <$dir/GPL*>;
foreach (@files) {
	guess_license_from_file("$_");
}

 
if ($python != 1) {
        guess_description($dir);
}

#
# Output of bbfile file
#
write_bbfile();
chdir($orgdir);
exit 0;

#
# Output of the yaml file
#


if ($oscmode == 1) {
	print "Creating OBS project $name ...\n";
	system("osc mkpac $name &> /dev/null");
	system("mkdir $name &> /dev/null");
	chdir($name);
	system("mv ../$name*\.tar\.* .");
}

write_yaml();
print "Building package   ....\n";

if ($oscmode == 0) {
	guess_files_from_rpmbuild();
} else {
 	guess_files_from_oscbuild();
}

apply_files_rules();

$printed_subpackages = 0;
write_yaml();

process_rpmlint();

print "Spectacle creation complete.\n";
